<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>6.着色器实现像素动画-随机粒子动画</title>
    <style>
        canvas{
            border:1px solid #aaa;
            margin: 0 auto;
            display: block;
        }
    </style>
</head>
<body>
    <canvas width="554" height="554"></canvas>
    <script src="/common/lib/gl-renderer.js"></script>

    <script type="module">
        import { loadImage, toPolar, fromPolar } from "/common/lib/utils.js";
        import {Animator} from '/common/lib/animator.js';
        

        /**
         * gl-renderer五步法
         * 1.创建renderer对象
         * 2.创建并启用webgl程序
         * 3.设置uniform变量
         * 4.将定点数据送入缓冲区
         * 5.渲染
         * 
        */
        // 1.
        let canvas = document.querySelector("canvas");
        const renderer = new GlRenderer(canvas);

        // 2.
        const vertex = `
            attribute vec2 a_vertexPosition;
            attribute vec2 uv;
            varying vec2 vUv;

            void main(){
                gl_PointSize = 1.0;
                vUv = uv;
                gl_Position = vec4(a_vertexPosition, 1.0, 1.0);
            }
        `
        // 
        const fragment = `
        #ifdef GL_ES
            precision highp float;
            #endif

            uniform float uTime;
            varying vec2 vUv;

            float random (vec2 st) {
                return fract(sin(dot(st.xy,
                                    vec2(12.9898,78.233)))*
                    43758.5453123);
            }
            // 二维噪声，对st与方形区域的四个顶点插值
            float noise(vec2 st) {
                vec2 i = floor(st);
                vec2 f = fract(st);
                vec2 u = f * f * (3.0 - 2.0 * f);
                // st与方形区域的四个顶点做插值计算
                return mix( mix( random( i + vec2(0.0,0.0) ), random( i + vec2(1.0,0.0) ), u.x),
                            mix( random( i + vec2(0.0,1.0) ), random( i + vec2(1.0,1.0) ), u.x), u.y);
            }
            float sdf_circle(vec2 st, vec2 c, float r) { 
                return 1.0 - length(st - c) / r;
            }
            void main() {
                vec2 st = vUv;
                float rx = mix(-0.2, 0.2, noise(vec2(7881.32, 0) + random(st) + uTime * 0.0008));
                float ry = mix(-0.2, 0.2, noise(vec2(0, 1433.59) + random(st) + uTime * 0.0008));
                float dis = distance(st, vec2(0.5));
                dis = pow((1.0 - dis), 2.0);
                float d = sdf_circle(st + vec2(rx, ry), vec2(0.5), 0.2);
                d = smoothstep(0.0, 0.1, d);

                gl_FragColor = vec4(dis * d * vec3(1.0), 1.0);
            }
        `
        const program = renderer.compileSync(fragment, vertex);
        renderer.useProgram(program);

        renderer.uniforms.uTime = 0.0
        
        renderer.setMeshData([{
            positions: [
                [-1, -1],
                [-1, 1],
                [1, 1],
                [1, -1],
            ],
            attributes: {
                uv: [
                    [0, 0],
                    [0, 1],
                    [1, 1],
                    [1, 0],
                ],
            },
            cells: [[0, 1, 2], [2, 0, 3]],
        }]);
        renderer.render();

        function update(uTime){
            renderer.uniforms.uTime = uTime
            requestAnimationFrame(update)
        }

        update(0.0)

    </script>
</body>
</html>